/*
 * TMap Designer - A Thematic Map design software
 * Copyright (C) 2006 World Health Organization
 * http://www.who.int
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package who.tmap.ui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.JTextComponent;

import who.tmap.bo.Attrs;
import who.tmap.common.TMapException;
import who.tmap.toolkit.MappingToolKit;
import who.tmap.toolkit.shape.MapShape;
import who.tmap.toolkit.shape.PolygonShape;
import who.tmap.ui.util.MiscUIHelper;
import who.tmap.ui.util.NonMatchingInfo;
import who.tmap.ui.util.NonMatchingInfoTableModel;
import who.tmap.ui.util.jsorttable.CellRenderer;

/**
 * A dialog to edit non matching polygons and data
 * 
 * @see NonMatchingInfoTableModel
 * @see NonMatchingInfo
 * @author Administrator
 *
 */
public class JDialogEditNonMatchingInfo extends JDialog {

	private static final long serialVersionUID = 1L;
	//private static final Color BG_CELL_COLOR =new Color( 194, 213, 232 ); 
	
	private List<NonMatchingInfo> orphans;
	private List<NonMatchingInfo> nmd;
	
	private NonMatchingInfoTableModel orphansTableModel;
	private NonMatchingInfoTableModel nmdTableModel;	
	
	private MappingToolKit mtk;
	
	private boolean okPressed =false;
	
	private JPanel jContentPane = null;
	private JSplitPane jSplitPane = null;
	private JPanel jPanelButtons = null;
	private JButton jButtonOK = null;
	private JButton jButtonCancel = null;
	private JScrollPane jScrollPanePolygons = null;
	private JTable jTablePolygons = null;
	private JScrollPane jScrollPaneData = null;
	private JTable jTableData = null;

	/**
	 * @param owner
	 */
	public JDialogEditNonMatchingInfo(Frame owner, MappingToolKit mtk ) {
		super(owner);
		
		this.mtk =mtk;
		
		try {
			orphans =new ArrayList<NonMatchingInfo>();
			
			for( String polygonName : mtk.getOrphanPolygons().keySet() ) {
				orphans.add( new NonMatchingInfo( polygonName ) );
			}
			
			nmd =new ArrayList<NonMatchingInfo>();
			for( String entry : mtk.getNonMatchingData() ) {
				nmd.add( new NonMatchingInfo( entry ) );
			}
		} catch (TMapException e) {
			new MiscUIHelper().displayErrorMessage( null, e );
		}
		
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(600, 400);
		this.setTitle("Edit Non Matching Information");
		this.setContentPane(getJContentPane());
		this.addWindowListener(new WindowAdapter() {
			public void windowActivated(WindowEvent e) {
				getJSplitPane().setDividerLocation( 0.5 );
			}
		});
		this.setLocationRelativeTo(null);
		
		this.setAlwaysOnTop( isModal() );
		
		getRootPane().setDefaultButton( getJButtonOK() );
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			jContentPane = new JPanel();
			jContentPane.setLayout(new BorderLayout());
			jContentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
			jContentPane.add(getJSplitPane(), BorderLayout.CENTER);
			jContentPane.add(getJPanelButtons(), BorderLayout.SOUTH);
		}
		return jContentPane;
	}

	/**
	 * This method initializes jSplitPane	
	 * 	
	 * @return javax.swing.JSplitPane	
	 */
	private JSplitPane getJSplitPane() {
		if (jSplitPane == null) {
			jSplitPane = new JSplitPane();
			jSplitPane.setOneTouchExpandable(true);
			jSplitPane.setResizeWeight(0.5);
			jSplitPane.setLeftComponent(getJScrollPanePolygons());
			jSplitPane.setRightComponent(getJScrollPaneData());
		}
		return jSplitPane;
	}

	/**
	 * This method initializes jPanelButtons	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	private JPanel getJPanelButtons() {
		if (jPanelButtons == null) {
			jPanelButtons = new JPanel();
			jPanelButtons.add(getJButtonOK(), null );
			jPanelButtons.add(getJButtonCancel(), null );
		}
		return jPanelButtons;
	}

	/**
	 * This method initializes jButtonOK	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonOK() {
		if (jButtonOK == null) {
			jButtonOK = new JButton();
			jButtonOK.setText("OK");
			jButtonOK.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					applyModifications();
					setVisible( false );
					okPressed =true;
				}
			});
		}
		return jButtonOK;
	}

	/**
	 * This method initializes jButtonCancel	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getJButtonCancel() {
		if (jButtonCancel == null) {
			jButtonCancel = new JButton();
			jButtonCancel.setText("Cancel");
			jButtonCancel.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					setVisible( false );
				}
			});
		}
		return jButtonCancel;
	}

	/**
	 * This method initializes jScrollPanePolygons	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPanePolygons() {
		if (jScrollPanePolygons == null) {
			jScrollPanePolygons = new JScrollPane();
			jScrollPanePolygons.setViewportView(getJTablePolygons());
		}
		return jScrollPanePolygons;
	}

	/**
	 * This method initializes jTablePolygons	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJTablePolygons() {
		if (jTablePolygons == null) {
			orphansTableModel = new NonMatchingInfoTableModel();
			orphansTableModel.setNonMatchingInfo( orphans );
			orphansTableModel.setColumnName( "Orphan polygons" );
			
		    jTablePolygons = new JTable( orphansTableModel ) {
				 
				//  Select the text when the cell starts editing
				//  a) text will be replaced when you start typing in a cell
				//  b) text will be selected when you use F2 to start editing
				//  c) caret is placed at end of text when double clicking to start editing
				public Component prepareEditor(
					TableCellEditor editor, int row, int column)
				{
					Component c = super.prepareEditor(editor, row, column);
	 
					if (c instanceof JTextComponent)
					{
						((JTextField)c).selectAll();
					}
	 
					return c;
				}
				
			    /**
			     * Color every other row
			     */
				public Component prepareRenderer( TableCellRenderer renderer
			          						  , int rowIndex, int vColIndex ) {
				  Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
				  if (rowIndex % 2 == 0 ) {
					  c.setBackground( MiscUIHelper.TABLE_CELL_BG_COLOR );
				  } else {
					  // If not shaded, match the table's background
					  c.setBackground(getBackground());
					  if ( c.getBackground().equals( c.getForeground() ) ) {
						  c.setForeground( Color.black );
					  }
				  }
				  return c;
				}
			};
			
			CellRenderer cr =new CellRenderer();
			jTablePolygons.setDefaultRenderer(Object.class, cr);
			
			jTablePolygons.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
		}
		
		return jTablePolygons;
	}

	/**
	 * This method initializes jScrollPaneData	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPaneData() {
		if (jScrollPaneData == null) {
			jScrollPaneData = new JScrollPane();
			jScrollPaneData.setViewportView(getJTableData());
		}
		return jScrollPaneData;
	}

	/**
	 * This method initializes jTableData	
	 * 	
	 * @return javax.swing.JTable	
	 */
	private JTable getJTableData() {
		if (jTableData == null) {
			nmdTableModel = new NonMatchingInfoTableModel();
			nmdTableModel.setNonMatchingInfo( nmd );
			nmdTableModel.setColumnName( "Non matching data" );
			
			jTableData = new JTable( nmdTableModel ) {
				
				//  Select the text when the cell starts editing
				//  a) text will be replaced when you start typing in a cell
				//  b) text will be selected when you use F2 to start editing
				//  c) caret is placed at end of text when double clicking to start editing
				public Component prepareEditor(
					TableCellEditor editor, int row, int column)
				{
					Component c = super.prepareEditor(editor, row, column);
	 
					if (c instanceof JTextComponent)
					{
						((JTextField)c).selectAll();
					}
	 
					return c;
				}
				
				  /**
				   * Color every other row
				   */
				  public Component prepareRenderer( TableCellRenderer renderer
				          						  , int rowIndex, int vColIndex ) {
					  Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
					  if (rowIndex % 2 == 0 ) {
						  c.setBackground( MiscUIHelper.TABLE_CELL_BG_COLOR );
					  } else {
						  // If not shaded, match the table's background
						  c.setBackground( getBackground() );
					  }
					  return c;
				  }
			};
			
			CellRenderer cr =new CellRenderer();
			jTableData.setDefaultRenderer(Object.class, cr);
			
			jTableData.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
		}
		
		return jTableData;
	}
	
	@SuppressWarnings("unchecked")
	private void applyModifications() {
		if ( orphansTableModel.isDirty() ) {
			List<NonMatchingInfo> nmis =new ArrayList<NonMatchingInfo>();
			
			for( NonMatchingInfo nmi : orphans ) {
				if ( nmi.isUpdated() ) {
					nmis.add( nmi );
				}
			}
			
			for( MapShape ms : mtk.getShapes() ) {
				if ( ms instanceof PolygonShape ) {
					PolygonShape ps =(PolygonShape)ms;
					
					for( NonMatchingInfo nmi : nmis ) {
						if ( ps.getName() != null && ps.getName().equalsIgnoreCase( nmi.getOriginalVal() ) ) {
							ps.setName( nmi.getUpdatedVal() );
						}
					}
				}
			}
		}
		
		if ( nmdTableModel.isDirty() ) {
			List<NonMatchingInfo> nmis =new ArrayList<NonMatchingInfo>();
			
			for( NonMatchingInfo nmi : nmd ) {
				if ( nmi.isUpdated() ) {
					nmis.add( nmi );
				}
			}
			
			Attrs attrs =mtk.getThematicMap().getData();
			
			for( List row : attrs.getRows() ) {
				Object joinId =row.get( attrs.getJoinIdIdx() );
				
				if ( joinId instanceof String && joinId != null ) {
					for( NonMatchingInfo nmi : nmis ) {
						if ( ((String)joinId).equalsIgnoreCase( nmi.getOriginalVal() ) ) {
							row.set( attrs.getJoinIdIdx(), nmi.getUpdatedVal() );
						}
					}
				}
				
			}
		}
	}

	public boolean isOkPressed() {
		return okPressed;
	}
	
	public boolean isUpdated() {
		return orphansTableModel.isDirty() || nmdTableModel.isDirty();
	}

}
